package wili.attrMapping.core;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import wili.attrMapping._user.b1.AttConst;
import wili.attrMapping._user.b1.AttMapingRule_main;
import wili.attrMapping.core.del.AttsBean;
import wili.attrMapping.core.del.OldEditable;
import wili.attrMapping.file.JsonFile;
import wili.c.Ca;

/**
 * @author weila 2022年10月3日
 */
public abstract class JsonUserConf implements UserConf, AttConst {
	public final AttsDefine attDefine;

	protected final String ruleFile;

	public JsonUserConf(String ruleFile, AttsDefine def) {
		Att9.inc = ParseOutNewAttValue9.inc = 0;
		this.ruleFile = ruleFile;
		this.attDefine = def;
		def.conf = this;
	}

	@Override
	public List<File> getOldFiles() {
		Ca.asert(false, "12-04");
		File[] ff = new File(DemoDIR, "a1")
				.listFiles(f -> f.getName().matches(".+\\.json") && !f.getName().endsWith(".txt.json"));
		return Arrays.asList(ff);
	}

	private List<AttsFile> newFiles;

	@Override
	public List<AttsFile> getNewAttsFiles() {
		Ca.asert(false, "12-04");
		if (newFiles == null) {
			File[] ff = new File(DemoDIR, "a2").listFiles(f -> f.getName().matches(".+\\.json"));
			newFiles = Stream.of(ff).map(file -> new JsonFile(file)).collect(Collectors.toList());
		}
		return newFiles;
	}

	@Override
	public abstract String replaceFileContent_atLast(String st);

	@Override
	public Atts createAtts(AttsFile afile, String key, Object obj, boolean isNewAtt) {
		Atts ret;
		if (this.attDefine.bean != null) {
			ret = AttsBean.newInst(OldEditable.class, attDefine, afile, key, obj, isNewAtt);
		} else {
			ret = new JsonAtts(attDefine, afile, key, obj, isNewAtt);
		}
		return ret;
	}

	@Override
	public AttsDefine getAttsDefine() {
		return this.attDefine;
	}

	public ValueMapingNode getMapingRule(ValueMapingNode rule) {
		if (rule != null)
			return rule;
		File file = new File(RuleDir, this.ruleFile);
		if (!file.exists() && !ruleFile.contains(".")) {
			file = new File(RuleDir, this.ruleFile + ".txt");
		}
		return this.getMapingRule(rule, file);
	}

	@Override
	public ValueMapingNode genRuleOf_oldNewAtts(boolean genRuleTemplate, Atts oldAtts, Atts newAtts,
			ValueMapingNode ruleRoot) {
		return JsonUserConf9.genRuleOfOldNewAtts_then_checkInconsistent(genRuleTemplate, oldAtts, newAtts, ruleRoot,
				this);
	}

	@Override
	public Set<AttsFile> valueOfNewAtts_inOldFile(boolean isCheck, AttsFile oldFile, AttsDefine attsDefine,
			ValueMapingNode ruleRoot, AttMapingRule_main cont) {
		return ParseOutNewAttValue9.parseOutNewAttValue_fromOldFile(isCheck, oldFile, attsDefine, ruleRoot, cont);
	}

	@Override
	public void valueOfNewAtts(Atts oldAtts, ValueMapingNode ruleRoot, Atts newAtts) {
		// 规则值 vs 旧值 ~>新值
		ValueMapingNode ruleLeaf;
		{// 顺着属性序列走向规则叶
			ruleLeaf = oldAtts.getRuleTarget(ruleRoot);
			if (ruleLeaf == null)
				return;
			ruleLeaf = ruleLeaf.son(newAtts.objName, null);
		}
		Att9.usage("新属性=fun(规则，旧属性)");
		this.attDefine.valueOfNewAtt(ruleLeaf.value, oldAtts);
	}

	public AttsFile attsFileOf(Object key) {
		AttsFile ret = MAP.get(key);
		if (ret == null) {
			if (key instanceof File) {
				MAP.put(key, ret = new JsonFile((File) key));
			} else {
				//MAP.put(key, ret = new JsonFile((String) key));
			}
		}
		return ret;
	}

	private Map<Object, AttsFile> MAP = new HashMap<>();
}
